﻿using System;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace TISS_Add_in
{
    public static class DemonstrativoRetorno
    {
        public static docTissDemonstrativo.ws_solicitacaoDemonstrativoRetorno GeraSolicitacaoDemonstrativo(long codPrestadorOrigem, string regANSDestino, long numeroProtocolo, TISS_Add_in.docTissDemonstrativo.st_tipoDemonstrativo tipoDemonstrativo)
        {
            docTissDemonstrativo.ws_solicitacaoDemonstrativoRetorno solicitacaoDemonstrativoRetorno = new TISS_Add_in.docTissDemonstrativo.ws_solicitacaoDemonstrativoRetorno();

            solicitacaoDemonstrativoRetorno.cabecalho =
                (docTissDemonstrativo.cabecalhoTransacao)Cabecalho.GeraCabecalho(codPrestadorOrigem, regANSDestino, tipoTransacao.SOLIC_DEMONSTRATIVO_RETORNO);

            if (solicitacaoDemonstrativoRetorno.cabecalho != null)
            {
                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno = new TISS_Add_in.docTissDemonstrativo.ct_solicitacaoDemonstrativoPagamento();
                docTissDemonstrativo.ct_solicitacaoDemonstrativoPagamento solicitacao = new TISS_Add_in.docTissDemonstrativo.ct_solicitacaoDemonstrativoPagamento();

                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.dadosPrestador = new TISS_Add_in.docTissDemonstrativo.ct_contratado();

                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.dadosPrestador.identificacao = new TISS_Add_in.docTissDemonstrativo.ct_identificacaoPrestadorExecutante();
                //solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.dadosPrestador.identificacao = (docTissDemonstrativo.ct_identificacaoPrestadorExecutante)solicitacaoDemonstrativoRetorno.cabecalho.origem.Item;
                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.dadosPrestador.identificacao.Item = solicitacaoDemonstrativoRetorno.cabecalho.origem.Item.ToString();

                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.dadosPrestador.nomeContratado = Globals.ThisAddIn.PrestadorNome;
                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.registroANS = regANSDestino;
                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.dataSolicitacao = solicitacaoDemonstrativoRetorno.cabecalho.identificacaoTransacao.dataRegistroTransacao;;

                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.tipoDemonstrativo = tipoDemonstrativo;

                //TODO: OV - enviar requisicao de mais de um lote?
                string[] numeros = new string[1];
                docTissDemonstrativo.ItemsChoiceType[] numerosTipo = new TISS_Add_in.docTissDemonstrativo.ItemsChoiceType[1];
                numeros[0] = numeroProtocolo.ToString();
                numerosTipo[0] = TISS_Add_in.docTissDemonstrativo.ItemsChoiceType.numeroProtocolo;
                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.Items = numeros;
                solicitacaoDemonstrativoRetorno.solicitacaoDemonstrativoRetorno.ItemsElementName = numerosTipo;

                #region Rodapé

                //Fechando a mensagem e Serializando em Memória
                Stream streamMensagem = new MemoryStream();
                streamMensagem = XMLUtils.Serializa(solicitacaoDemonstrativoRetorno, null);

                //Fim da Mensagem: HASH
                //Calculando e inserindo o Hash da Mensagem
                solicitacaoDemonstrativoRetorno.hash = AddinUtils.CalculateMD5Hash(streamMensagem);

                #endregion

                return solicitacaoDemonstrativoRetorno;
            }
            return null;
        }

        public static bool RecebeDemonstrativoRetorno(docTissDemonstrativo.ws_DemonstrativoRetorno demonstrativoRetorno, TipoGuia tipoDemonstrativo, long codPrestador, string regANS, long loteCod)
        {
            XmlSerializer xs;
            MemoryStream memoryStream = new MemoryStream();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.GetEncoding("ISO-8859-1"));

            switch (tipoDemonstrativo)
            {
                // Demonstrativo de Pagamento
                case TipoGuia.Demonstrativo_Pagamento:

                    docTissDemonstrativo.ct_demonstrativoPagamento pagamento = new TISS_Add_in.docTissDemonstrativo.ct_demonstrativoPagamento();
                    pagamento = (docTissDemonstrativo.ct_demonstrativoPagamento)demonstrativoRetorno.demonstrativoRetorno.Items[0];

                    xs = new XmlSerializer(typeof(docTissDemonstrativo.ct_demonstrativoPagamento));
                    memoryStream = new MemoryStream();
                    xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.GetEncoding("ISO-8859-1"));

                    xs.Serialize(xmlTextWriter, pagamento);

                    break;
                // Demonstrativo de Análise da Conta Médica
                case TipoGuia.Demonstrativo_Análise_Conta:

                    docTissDemonstrativo.ct_demonstrativoAnaliseConta analiseConta = new TISS_Add_in.docTissDemonstrativo.ct_demonstrativoAnaliseConta();
                    analiseConta = (docTissDemonstrativo.ct_demonstrativoAnaliseConta)demonstrativoRetorno.demonstrativoRetorno.Items[0];

                    xs = new XmlSerializer(typeof(docTissDemonstrativo.ct_demonstrativoAnaliseConta));
                    memoryStream = new MemoryStream();
                    xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.GetEncoding("ISO-8859-1"));

                    xs.Serialize(xmlTextWriter, analiseConta);

                    break;
                // Demonstrativo de Pagamento - Odontologia
                case TipoGuia.Demonstrativo_Odontologia:

                    //TODO: OV - Demonstrativo Odonto

                    break;
                default:
                    return false;
            }

            memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
            byte[] demonstrativo = memoryStream.ToArray();

            return DBConnect.CommandDemonstrativo.InsereDemonstrativoRetorno (Convert.ToInt32(tipoDemonstrativo),
                Convert.ToInt64(demonstrativoRetorno.cabecalho.identificacaoTransacao.sequencialTransacao), codPrestador, regANS, loteCod, demonstrativo);
        }

        public static object BuscaDemonstrativoRetorno(TipoGuia tipoDemonstrativo, long demonstrativoCod)
        {
            DataTable dt = DBConnect.CommandDemonstrativo.SelecionaDemonstrativo(demonstrativoCod);
            byte[] demonstrativoByteArray = (byte[])dt.Rows[0]["demonstrativo"];

            switch (tipoDemonstrativo)
            {
                case TipoGuia.Demonstrativo_Pagamento:
                    MemoryStream streamPagamento = new MemoryStream(demonstrativoByteArray);
                    return (docTissDemonstrativo.ct_demonstrativoPagamento)XMLUtils.Deserializa(streamPagamento, typeof(docTissDemonstrativo.ct_demonstrativoPagamento), null);

                case TipoGuia.Demonstrativo_Análise_Conta:
                    MemoryStream streamAnalise = new MemoryStream(demonstrativoByteArray);
                    return (docTissDemonstrativo.ct_demonstrativoAnaliseConta)XMLUtils.Deserializa(streamAnalise, typeof(docTissDemonstrativo.ct_demonstrativoAnaliseConta), null);

                case TipoGuia.Demonstrativo_Odontologia:

                    //TODO: OV - Demonstrativo Odonto

                    return null;
                default:
                    return null;
            }
        }
    }
}
